package src.main.java.action;

import java.math.BigInteger;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.ServletResponseAware;
import org.apache.struts2.interceptor.SessionAware;

import src.main.java.dao.PedidoDAO;
import src.main.java.entity.EnderecoTO;
import src.main.java.entity.EntregaTO;
import src.main.java.entity.PedidoDB;
import src.main.java.entity.PedidoTO;
import src.main.java.entity.ProdutoTO;
import src.main.java.modules.container.BancoCaller;
import src.main.java.modules.container.CartaoDeCreditoCaller;
import src.main.java.modules.container.EnderecoCaller;
import src.main.java.modules.container.EstoqueCaller;
import src.main.java.modules.container.LogisticaCaller;
import src.main.java.utils.ConvertPedidoTO;

import com.opensymphony.xwork2.ActionSupport;
import com.pagodabox.mc437_2012s2_banco_ws.ws.Boleto;

public class FinalizarCompraAction extends ActionSupport implements ServletRequestAware, ServletResponseAware, SessionAware {
	
	private HttpServletRequest request;
	private HttpServletResponse response;
	private static Map<String, Object> session;
	
	private EnderecoTO endereco;
	private EntregaTO entrega;
	private String transportadora;
	private String feedback;
	private String action;
	private Integer tipoPagamento;
	private Long cartaoNumero;
	private Integer cartaoCodigo;
	private String cartaoBandeira;
	private String cartaoValidade;
	
	private PedidoDAO pedidoDAO;
	
	@Action(value = "/finalizar_passo2", results = {
			@Result(location = "finalizar_passo2.jsp", name = "ok"),
			@Result(location = "actionRedirect.jsp", name = "sessionExpired")}
	)
	public String finalizarPasso2(){
		PedidoTO pedido = (PedidoTO) session.get("pedido");
		if (pedido == null){
			action = "";
			return "sessionExpired";
		}
		
		String cep = pedido.getEndereco().getCep();
		List<ProdutoTO> produtos = pedido.getProdutos();
		
		ws_pkg.Produto[] list_produtos = new ws_pkg.Produto[produtos.size()];
		
		int i = 0;
		for(ProdutoTO p : produtos){
			ws_pkg.Produto pws = new ws_pkg.Produto();
			pws.setId_produto(p.getCodigo());
			pws.setPeso(p.getPeso().intValue());
			pws.setQuantidade(p.getQuantidade());
			pws.setVolume(p.getVolume());
			list_produtos[i] = pws;
			i++;
		}
		
		entrega = LogisticaCaller.calcularTodosFretes(cep, list_produtos);
		pedido.setEntrega(entrega);
		session.put("pedido", pedido);
		
		return "ok";
	}
	
	@Action(value = "/finalizar_passo3", results = {
			@Result(location = "finalizar_passo3.jsp", name = "ok"),
			@Result(location = "actionRedirect.jsp", name = "sessionExpired")}
	)
	public String finalizarPasso3(){
		PedidoTO pedido = (PedidoTO) session.get("pedido");
		if (pedido == null){
			action = "";
			return "sessionExpired";
		}
		
		entrega = pedido.getEntrega();
		
		if ("pac".equals(transportadora)){
			entrega.setTransportadora("pac");
			entrega.setPrazo(entrega.getPac().getPrazo());
			entrega.setFrete(entrega.getPac().getFrete());
		} else if ("sedex".equals(transportadora)){
			entrega.setTransportadora("sedex");
			entrega.setPrazo(entrega.getSedex().getPrazo());
			entrega.setFrete(entrega.getSedex().getFrete());
		} else if ("esedex".equals(transportadora)){
			entrega.setTransportadora("esedex");
			entrega.setPrazo(entrega.getEsedex().getPrazo());
			entrega.setFrete(entrega.getEsedex().getFrete());
		} else if ("fedex".equals(transportadora)){
			entrega.setTransportadora("fedex");
			entrega.setPrazo(entrega.getFedex().getPrazo());
			entrega.setFrete(entrega.getFedex().getFrete());
		}
		
		pedido.setEntrega(entrega);
		pedido.setTotal(pedido.getSubTotal() + entrega.getFrete());
		System.out.println(pedido.getTotal());
		session.put("pedido", pedido);
		
		return "ok";
	}
	
	@Action(value = "/novoEndereco", results = {
			@Result(location = "enderecoNovo.jsp", name = "ok")}
	)
	public String novoEndereco(){
		return "ok";
	}
	
	@Action(value = "/trocarEndereco", results = {
			@Result(location = "finalizar.jsp", name = "sucess"),
			@Result(location = "enderecoNovo.jsp", name = "fail"),
			@Result(location = "actionRedirect.jsp", name = "sessionExpired")}
	)
	public String trocarEndereco(){
		PedidoTO pedido = (PedidoTO) session.get("pedido");
		if (pedido == null){
			action = "";
			return "sessionExpired";
		}
		
		boolean erro = false;
		if (endereco != null && endereco.getCep() != null && !endereco.getCep().equals("")){
			String cep = endereco.getCep().replaceAll("-", "");
			endereco = EnderecoCaller.buscaPorCep(cep);
			if (!endereco.getErro().equals(new BigInteger("0")) ){
				erro = true;
			}
		} else {
			erro = true;
		}

		if(erro){
			feedback = "naoExiste";
			return "fail";
		} else {
			pedido.setEndereco(endereco);
			session.put("pedido", pedido);
			feedback = "sucessoEndereco";
		}
		
		return "sucess";
		
	}
	
	@Action(value = "/finalizar_compra", results = {
			@Result(location = "sucesso.jsp", name = "sucess"),
			@Result(location = "finalizar_passo3.jsp", name = "fail"),}
	)
	public String finalizarCompra(){
		PedidoTO pedido = (PedidoTO) session.get("pedido");
		if(tipoPagamento == 1){ //cartao
			Integer transacaoId = pagarComCartao(pedido);
			if(transacaoId == -1){ //erro na transacao do cartao
				feedback = "erroCartao";
				return "fail";
			}
			pedido.setIdTransacao(transacaoId);
			pedido.setTipoPagamento("cartao");
			System.out.println("Transacao do cartao: "+ transacaoId);
		}else{ //boleto
			Integer boletoId = emitirBoleto(pedido);
			pedido.setNumeroBoleto(boletoId);
			pedido.setTipoPagamento("boleto");
			System.out.println("Id do boleto: " + boletoId);
		}
		
		//atualiza o estoque
		for(ProdutoTO p : pedido.getProdutos()){
			Boolean alterouQuantidade = EstoqueCaller.alteraQuantidade(p.getCodigo(), (p.getQuantidade()*-1));
			System.out.println("Alterou quantidade do produto:"+p.getCodigo()+"?? "+alterouQuantidade + " :"+(p.getQuantidade()*-1));
		}

		ws_pkg.Produto[] list_produtos = new ws_pkg.Produto[pedido.getProdutos().size()];
		
		int i = 0;
		for(ProdutoTO p : pedido.getProdutos()){
			ws_pkg.Produto pws = new ws_pkg.Produto();
			pws.setId_produto(p.getCodigo());
			pws.setPeso(p.getPeso().intValue());
			pws.setQuantidade(p.getQuantidade());
			pws.setVolume(p.getVolume());
			list_produtos[i] = pws;
			i++;
		}
		
		int cadastro = LogisticaCaller.cadastraEntrega(4, 13083720, Integer.parseInt(pedido.getEndereco().getCep().replace("-", "")), converteTransportadora(pedido.getEntrega().getTransportadora()), list_produtos);
		System.out.println("Codigo da entrega: " + cadastro);
		//salva no pedido o ID da entrega
		pedido.getEntrega().setNumeroEntrega(cadastro);
		
		if(pedidoDAO == null)
			pedidoDAO = new PedidoDAO();
		PedidoDB pedidoDB = ConvertPedidoTO.toPedidoDB(pedido);
		Long id = pedidoDAO.savePedido(pedidoDB);
		
		pedido.setId(id);
		session.put("pedido", pedido);
		return "sucess";
	}
	
	private int converteTransportadora(String transportadora){
		if ("pac".equals(transportadora)){
			return 3;
		} else if ("sedex".equals(transportadora)){
			return 1;
		} else if ("esedex".equals(transportadora)){
			return 2;
		} else if ("fedex".equals(transportadora)){
			return 4;
		}
		return 0;
	}
	
	private Integer pagarComCartao(PedidoTO pedido){
		Integer transactionId = CartaoDeCreditoCaller.doTransaction(pedido.getValorTotal(), cartaoBandeira, cartaoNumero, cartaoCodigo, cartaoValidade, pedido.getCliente());
		return transactionId;
	}
		
	private Integer emitirBoleto(PedidoTO pedido){
		Boleto boleto = null;
		
		if(pedido.getTotal()!=null && pedido.getCliente()!=null && pedido.getCliente().getNome()!=null){
			boleto = BancoCaller.emitirBoleto("17.561.933/0001-50", "710d8af9ddd5605c9d01499c049c5385", pedido.getCliente().getNome(), pedido.getTotal().floatValue());
		}
		else if(pedido.getCliente()==null || pedido.getCliente().getNome()==null){
			//OPA NENEM, ESQUECEU DO NOME DO MANOLO
		}
		else if(pedido.getTotal() == null){
			//OPA NENEM, ESQUECEU O TOTAL
		}
		
		pedido.setNumeroBoleto(boleto.getId());
		
		return boleto.getId();
	}
	
	@Override
	public void setServletResponse(HttpServletResponse arg0) {
		this.response = arg0;
	}

	@Override
	public void setServletRequest(HttpServletRequest arg0) {
		this.request = arg0;
	}

	@Override
	public void setSession(Map<String, Object> arg0) {
		this.session = arg0;		
	}

	public EnderecoTO getEndereco() {
		return endereco;
	}

	public void setEndereco(EnderecoTO endereco) {
		this.endereco = endereco;
	}

	public String getFeedback() {
		return feedback;
	}

	public void setFeedback(String feedback) {
		this.feedback = feedback;
	}

	public EntregaTO getEntrega() {
		return entrega;
	}

	public void setEntrega(EntregaTO entrega) {
		this.entrega = entrega;
	}

	public String getTransportadora() {
		return transportadora;
	}

	public void setTransportadora(String transportadora) {
		this.transportadora = transportadora;
	}

	public String getAction() {
		return action;
	}

	public void setAction(String action) {
		this.action = action;
	}

	public Integer getTipoPagamento() {
		return tipoPagamento;
	}

	public void setTipoPagamento(Integer tipoPagamento) {
		this.tipoPagamento = tipoPagamento;
	}

	public Long getCartaoNumero() {
		return cartaoNumero;
	}

	public void setCartaoNumero(Long cartaoNumero) {
		this.cartaoNumero = cartaoNumero;
	}

	public Integer getCartaoCodigo() {
		return cartaoCodigo;
	}

	public void setCartaoCodigo(Integer cartaoCodigo) {
		this.cartaoCodigo = cartaoCodigo;
	}

	public String getCartaoBandeira() {
		return cartaoBandeira;
	}

	public void setCartaoBandeira(String cartaoBandeira) {
		this.cartaoBandeira = cartaoBandeira;
	}

	public String getCartaoValidade() {
		return cartaoValidade;
	}

	public void setCartaoValidade(String cartaoValidade) {
		this.cartaoValidade = cartaoValidade;
	}
}
